import 'dart:async';
import 'package:flame/effects.dart';
import 'package:flutter/material.dart';
import 'package:flame/components.dart' hide Timer;
import 'package:flame/flame.dart';
import 'package:freedom/page/mahjong/common/card_build.dart';
import 'package:freedom/page/mahjong/common/mahjong_context.dart';
import 'package:freedom/page/mahjong/event/user_swap_event.dart';
import 'package:freedom/page/mahjong/util/user_location.dart';

/// 有三种情况
///
///
/// 1 对家交换
/// 2 顺时针交换
/// 3 逆时针交换
class SwapCardAction extends PositionComponent {
  SwapCardAction()
      : super(
            position: Vector2(0, 0),
            size: Vector2(
                MahjongContext().screenWidth, MahjongContext().screenHeight));
  double length = MahjongContext().screenHeight / 10, headHeight = 20;

  SwapCardComponent? _bottom;
  SwapCardComponent? _left;
  SwapCardComponent? _right;
  SwapCardComponent? _top;

  Map<Direction, List<int>?> swapCardInfo = {};

/*   var riveSource;
  RiveComponent? swapComponent; */
  /*  riveSource =
        await loadArtboard(RiveFile.asset('assets/rive/mahjong/swapcard.riv'));
 */

  @override
  FutureOr<void> onLoad() async {
    //1秒后这个i行
    /* swapCard(Direction.BOTTOM, swapCard: [1, 2, 3]);
    swapCard(Direction.TOP, swapCard: [3, 4, 5]);
    swapCard(Direction.RIGHT, swapCard: [6, 7, 8]);
    swapCard(Direction.LEFT, swapCard: [22, 22, 23]);
    
    Future.delayed(const Duration(milliseconds: 1000), () {
      startSwap(3, null, () {});
    }); */
    super.onLoad();
  }

  /* SimpleAnimation? controller; */
/*     swapComponent?.removeFromParent();
    swapComponent = null; */
  // 'btchange' 对家交换 'rlchange' 顺时针交换 'lrchange' 逆时针交换

  // 开始动画交换
  void startSwap(
      int diceCount, List<int>? currentInCard, Function callBack) async {
    var time = 1.0;
    int userCount = MahjongContext.userCount;
    int remainder = diceCount % userCount;
    int addNumber = remainder == 0 ? userCount - 1 : remainder - 1;
    String controllerName = 'lrchange';
    if (userCount == 4) {
      switch (addNumber) {
        case 0:
          controllerName = 'btchange';
          break;
        case 1:
          controllerName = 'lrchange';
          break;
        case 2:
          controllerName = 'btchange';
          break;
        case 3:
          controllerName = 'rlchange';
          break;
      }
    } else if (userCount == 2) {
      controllerName = 'btchange';
    } else if (userCount == 3) {
      switch (addNumber) {
        case 0:
          controllerName = 'lrchange';
          break;
        case 1:
          controllerName = 'lrchange';
          break;
        case 2:
          controllerName = 'rlchange';
          break;
      }
    }
    //逆时针交换
    if (controllerName == 'lrchange' && userCount == 4) {
      swapCardInfo[Direction.TOP] = _right?.swapCard;
      swapCardInfo[Direction.BOTTOM] = _left?.swapCard;
      swapCardInfo[Direction.LEFT] = _top?.swapCard;
      swapCardInfo[Direction.RIGHT] = _bottom?.swapCard;
      Path tlPath = Path()
        ..quadraticBezierTo(
            _left!.x - _top!.x, 0, _left!.x - _top!.x, _left!.y - _top!.y);
      _top?.add(MoveAlongPathEffect(
        tlPath,
        EffectController(duration: time),
      ));
      Path brPath = Path()
        ..quadraticBezierTo(_right!.x - _bottom!.x, 0, _right!.x - _bottom!.x,
            _right!.y - _bottom!.y);
      _bottom?.add(MoveAlongPathEffect(
        brPath,
        EffectController(duration: time),
      ));

      Path rtPath = Path()
        ..quadraticBezierTo(
            0, _top!.y - _right!.y, _top!.x - _right!.x, _top!.y - _right!.y);
      _right?.add(MoveAlongPathEffect(
        rtPath,
        EffectController(duration: time),
      ));

      Path lbPath = Path()
        ..quadraticBezierTo(0, _bottom!.y - _left!.y, _bottom!.x - _left!.x,
            _bottom!.y - _left!.y);
      _left?.add(MoveAlongPathEffect(
        lbPath,
        EffectController(duration: time),
      ));
      //逆时针交换
    } else if (controllerName == 'rlchange' && userCount == 4) {
      swapCardInfo[Direction.TOP] = _left?.swapCard;
      swapCardInfo[Direction.BOTTOM] = _right?.swapCard;
      swapCardInfo[Direction.LEFT] = _bottom?.swapCard;
      swapCardInfo[Direction.RIGHT] = _top?.swapCard;
      Path trPath = Path()
        ..quadraticBezierTo(
            _right!.x - _top!.x, 0, _right!.x - _top!.x, _right!.y - _top!.y);
      _top?.add(MoveAlongPathEffect(
        trPath,
        EffectController(duration: time),
      ));

      Path blPath = Path()
        ..quadraticBezierTo(_left!.x - _bottom!.x, 0, _left!.x - _bottom!.x,
            _left!.y - _bottom!.y);
      _bottom?.add(MoveAlongPathEffect(
        blPath,
        EffectController(duration: time),
      ));

      Path rbPath = Path()
        ..quadraticBezierTo(0, _bottom!.y - _right!.y, _bottom!.x - _right!.x,
            _bottom!.y - _right!.y);
      _right?.add(MoveAlongPathEffect(
        rbPath,
        EffectController(duration: time),
      ));

      Path ltPath = Path()
        ..quadraticBezierTo(
            0, _top!.y - _left!.y, _top!.x - _left!.x, _top!.y - _left!.y);
      _left?.add(MoveAlongPathEffect(
        ltPath,
        EffectController(duration: time),
      ));
      //逆时针交换
    } else if (controllerName == 'rlchange' && userCount == 3) {
      // 存储临时交换信息
      swapCardInfo[Direction.TOP] = _left?.swapCard;
      swapCardInfo[Direction.BOTTOM] = _top?.swapCard;
      swapCardInfo[Direction.LEFT] = _bottom?.swapCard;
      _top?.add(MoveToEffect(
        MahjongContext().bottomExportAreaPoint,
        EffectController(duration: time),
      ));
      _bottom?.add(MoveToEffect(
        MahjongContext().leftExportAreaPoint,
        EffectController(duration: time),
      ));
      Path ltPath = Path()
        ..quadraticBezierTo(
            0, _top!.y - _left!.y, _top!.x - _left!.x, _top!.y - _left!.y);
      _left?.add(MoveAlongPathEffect(
        ltPath,
        EffectController(duration: time),
      ));
      //顺时针交换
    } else if (controllerName == 'lrchange' && userCount == 3) {
      // 存储临时交换信息
      swapCardInfo[Direction.TOP] = _bottom?.swapCard;
      swapCardInfo[Direction.LEFT] = _top?.swapCard;
      swapCardInfo[Direction.BOTTOM] = _left?.swapCard;
      Path tlPath = Path()
        ..quadraticBezierTo(
            _left!.x - _top!.x, 0, _left!.x - _top!.x, _left!.y - _top!.y);
      _top?.add(MoveAlongPathEffect(
        tlPath,
        EffectController(duration: time),
      ));
      Path lbPath = Path()
        ..quadraticBezierTo(0, _bottom!.y - _left!.y, _bottom!.x - _left!.x,
            _bottom!.y - _left!.y);
      _left?.add(MoveAlongPathEffect(
        lbPath,
        EffectController(duration: time),
      ));
      _bottom?.add(MoveToEffect(
        MahjongContext().topExportAreaPoint,
        EffectController(duration: time),
      ));
    } else if (controllerName == 'btchange') {
      // 存储临时交换信息
      swapCardInfo[Direction.TOP] = _bottom?.swapCard;
      swapCardInfo[Direction.BOTTOM] = _top?.swapCard;
      swapCardInfo[Direction.LEFT] = _right?.swapCard;
      swapCardInfo[Direction.RIGHT] = _left?.swapCard;
      _top?.add(MoveToEffect(
        MahjongContext().bottomExportAreaPoint,
        EffectController(duration: time),
      ));
      _bottom?.add(MoveToEffect(
        MahjongContext().topExportAreaPoint,
        EffectController(duration: time),
      ));
      _right?.add(MoveToEffect(
        MahjongContext().leftExportAreaPoint,
        EffectController(duration: time),
      ));
      _left?.add(MoveToEffect(
        MahjongContext().rightExportAreaPoint,
        EffectController(duration: time),
      ));
    }
    removeAllInfo() {
      removeAll(Set.from(children));
      _bottom = null;
      _left = null;
      _top = null;
      _right = null;
      callBack();
    }

    add(TimerComponent(
        period: time.toInt() + 1,
        onTick: () {
          removeAllInfo();
          MahjongContext.diskAllUser.forEach((key, user) {
            List<int>? userInCard = swapCardInfo[user.direction];
            // 非回放模式  其它用户都是 null
            if (!MahjongContext().getPlayback) {
              userInCard = (key == MahjongContext.currentUser?.userId
                  ? currentInCard
                  : null);
            }
            MahjongContext.postUserEvent<UserSwapEvent>(
                key, UserSwapEvent(userInCard, SwapState.IN));
          });
        }));
  }

  void swapCard(Direction direction,
      {bool insert = true, List<int>? swapCard}) {
    switch (direction) {
      case Direction.BOTTOM:
        _bottom?.removeFromParent();
        _bottom = null;
        if (insert) {
          _bottom = SwapCardComponent(
              swapPosition: MahjongContext().bottomExportAreaPoint,
              swapCard: swapCard)
            ..priority = 0;
          add(_bottom!);
        }
      case Direction.RIGHT:
        _right?.removeFromParent();
        _right = null;
        if (insert) {
          _right = SwapCardComponent(
              swapPosition: MahjongContext().rightExportAreaPoint,
              swapCard: swapCard)
            ..priority = 0;
          add(_right!);
        }

      case Direction.LEFT:
        _left?.removeFromParent();
        _left = null;
        if (insert) {
          _left = SwapCardComponent(
              swapPosition: MahjongContext().leftExportAreaPoint,
              swapCard: swapCard)
            ..priority = 0;
          add(_left!);
        }
      case Direction.TOP:
        _top?.removeFromParent();
        _top = null;
        if (insert) {
          _top = SwapCardComponent(
              swapPosition: MahjongContext().topExportAreaPoint,
              swapCard: swapCard)
            ..priority = 0;
          add(_top!);
        }
      default:
        _left?.removeFromParent();
        _left = null;
        if (insert) {
          _left = SwapCardComponent(
              swapPosition: MahjongContext().leftExportAreaPoint,
              swapCard: swapCard)
            ..priority = 0;
          add(_left!);
        }
    }
  }
}

class SwapCardComponent extends PositionComponent implements OpacityProvider {
  Vector2? swapPosition;
  List<int>? swapCard;
  @override
  double opacity;
  SwapCardComponent({this.swapPosition, this.swapCard, this.opacity = 1})
      : super(position: swapPosition);

  @override
  FutureOr<void> onLoad() async {
    Vector2 cardSize = MahjongContext().bottomHandCard / 2.65;
    size = Vector2(cardSize.x * 3, cardSize.y);
    double marginLeft = cardSize.x - cardSize.x / 10;
    var swapImage = Flame.images.fromCache('mahjong/user/bottom/export_up.png');
    Vector2 start = Vector2(-cardSize.x * 1.5, -cardSize.y / 2);
    for (int i = 0, j = 3; i < j; i++) {
      PositionComponent component;
      if (swapCard != null &&
          swapCard!.length == 3 &&
          MahjongContext().getPlayback) {
        component = CardBuildUtil.topExport(start, swapCard![i],
            pointTo: null,
            size: MahjongContext().topTBCardSize,
            handCard: true);
      } else {
        component = SpriteComponent(
            sprite: Sprite(swapImage, srcPosition: Vector2.all(0.0)),
            size: cardSize,
            position: start);
      }
      add(component);
      start.x += marginLeft;
    }

    super.onLoad();
  }

  @override
  void render(Canvas canvas) {
    super.render(canvas);
  }
}
